import type {Locale} from 'ant-design-vue/es/locale';

import type {App} from 'vue';
import {ref} from 'vue';

import type {LocaleSetupOptions, SupportedLanguagesType} from './effects';
import {$t, loadLocalesMapFromDir, setupI18n as coreSetup, useI18n, i18n, loadLocaleMessages} from './effects';

import {preferences} from '#/components/common/core/preferences';

import antdEnLocale from 'ant-design-vue/es/locale/en_US';
import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN';
import dayjs from 'dayjs';

const antdLocale = ref<Locale>(antdDefaultLocale);

const modules = import.meta.glob('./langs/**/*.json');

const localesMap = loadLocalesMapFromDir(
    /\.\/langs\/([^/]+)\/(.*)\.json$/,
    modules,
);

/**
 * 加载应用特有的语言包
 * 这里也可以改造为从服务端获取翻译数据
 * @param lang
 */
async function loadMessages(lang: SupportedLanguagesType) {
    const [appLocaleMessages] = await Promise.all([
        localesMap[lang]?.(),
        loadThirdPartyMessage(lang),
    ]);

    return appLocaleMessages?.default;
}

/**
 * 加载第三方组件库的语言包
 * @param lang
 */
async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
    await Promise.all([loadAntdLocale(lang), loadDayjsLocale(lang)]);
}

/**
 * 加载dayjs的语言包
 * @param lang
 */
async function loadDayjsLocale(lang: SupportedLanguagesType) {
    let locale;
    switch (lang) {
        case 'en-US': {
            locale = await import('dayjs/locale/en');
            break;
        }
        case 'zh-CN': {
            locale = await import('dayjs/locale/zh-cn');
            break;
        }
        // 默认使用英语
        default: {
            locale = await import('dayjs/locale/en');
        }
    }
    if (locale) {
        dayjs.locale(locale);
    } else {
        console.error(`Failed to load dayjs locale for ${lang}`);
    }
}

/**
 * 加载antd的语言包
 * @param lang
 */
async function loadAntdLocale(lang: SupportedLanguagesType) {
    switch (lang) {
        case 'en-US': {
            antdLocale.value = antdEnLocale;
            break;
        }
        case 'zh-CN': {
            antdLocale.value = antdDefaultLocale;
            break;
        }
    }
}

async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
    await coreSetup(app, {
        defaultLocale: preferences.app.locale,
        loadMessages,
        missingWarn: !import.meta.env.PROD,
        ...options,
    });
}

export {$t, antdLocale, setupI18n, useI18n, i18n, loadLocaleMessages, SupportedLanguagesType};
